home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / linux / mtd / cfi.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  13.4 KB  |  535 lines

  1.  
  2. /* Common Flash Interface structures
  3.  * See http://support.intel.com/design/flash/technote/index.htm
  4.  */
  5.  
  6. #ifndef __MTD_CFI_H__
  7. #define __MTD_CFI_H__
  8.  
  9. #include <linux/delay.h>
  10. #include <linux/types.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/mtd/flashchip.h>
  13. #include <linux/mtd/map.h>
  14. #include <linux/mtd/cfi_endian.h>
  15. #include <linux/mtd/xip.h>
  16.  
  17. #ifdef CONFIG_MTD_CFI_I1
  18. #define cfi_interleave(cfi) 1
  19. #define cfi_interleave_is_1(cfi) (cfi_interleave(cfi) == 1)
  20. #else
  21. #define cfi_interleave_is_1(cfi) (0)
  22. #endif
  23.  
  24. #ifdef CONFIG_MTD_CFI_I2
  25. # ifdef cfi_interleave
  26. #  undef cfi_interleave
  27. #  define cfi_interleave(cfi) ((cfi)->interleave)
  28. # else
  29. #  define cfi_interleave(cfi) 2
  30. # endif
  31. #define cfi_interleave_is_2(cfi) (cfi_interleave(cfi) == 2)
  32. #else
  33. #define cfi_interleave_is_2(cfi) (0)
  34. #endif
  35.  
  36. #ifdef CONFIG_MTD_CFI_I4
  37. # ifdef cfi_interleave
  38. #  undef cfi_interleave
  39. #  define cfi_interleave(cfi) ((cfi)->interleave)
  40. # else
  41. #  define cfi_interleave(cfi) 4
  42. # endif
  43. #define cfi_interleave_is_4(cfi) (cfi_interleave(cfi) == 4)
  44. #else
  45. #define cfi_interleave_is_4(cfi) (0)
  46. #endif
  47.  
  48. #ifdef CONFIG_MTD_CFI_I8
  49. # ifdef cfi_interleave
  50. #  undef cfi_interleave
  51. #  define cfi_interleave(cfi) ((cfi)->interleave)
  52. # else
  53. #  define cfi_interleave(cfi) 8
  54. # endif
  55. #define cfi_interleave_is_8(cfi) (cfi_interleave(cfi) == 8)
  56. #else
  57. #define cfi_interleave_is_8(cfi) (0)
  58. #endif
  59.  
  60. #ifndef cfi_interleave
  61. #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
  62. static inline int cfi_interleave(void *cfi)
  63. {
  64.     BUG();
  65.     return 0;
  66. }
  67. #endif
  68.  
  69. static inline int cfi_interleave_supported(int i)
  70. {
  71.     switch (i) {
  72. #ifdef CONFIG_MTD_CFI_I1
  73.     case 1:
  74. #endif
  75. #ifdef CONFIG_MTD_CFI_I2
  76.     case 2:
  77. #endif
  78. #ifdef CONFIG_MTD_CFI_I4
  79.     case 4:
  80. #endif
  81. #ifdef CONFIG_MTD_CFI_I8
  82.     case 8:
  83. #endif
  84.         return 1;
  85.  
  86.     default:
  87.         return 0;
  88.     }
  89. }
  90.  
  91.  
  92. /* NB: these values must represents the number of bytes needed to meet the
  93.  *     device type (x8, x16, x32).  Eg. a 32 bit device is 4 x 8 bytes.
  94.  *     These numbers are used in calculations.
  95.  */
  96. #define CFI_DEVICETYPE_X8  (8 / 8)
  97. #define CFI_DEVICETYPE_X16 (16 / 8)
  98. #define CFI_DEVICETYPE_X32 (32 / 8)
  99. #define CFI_DEVICETYPE_X64 (64 / 8)
  100.  
  101.  
  102. /* Device Interface Code Assignments from the "Common Flash Memory Interface
  103.  * Publication 100" dated December 1, 2001.
  104.  */
  105. #define CFI_INTERFACE_X8_ASYNC        0x0000
  106. #define CFI_INTERFACE_X16_ASYNC        0x0001
  107. #define CFI_INTERFACE_X8_BY_X16_ASYNC    0x0002
  108. #define CFI_INTERFACE_X32_ASYNC        0x0003
  109. #define CFI_INTERFACE_X16_BY_X32_ASYNC    0x0005
  110. #define CFI_INTERFACE_NOT_ALLOWED    0xffff
  111.  
  112.  
  113. /* NB: We keep these structures in memory in HOST byteorder, except
  114.  * where individually noted.
  115.  */
  116.  
  117. /* Basic Query Structure */
  118. struct cfi_ident {
  119.     uint8_t  qry[3];
  120.     uint16_t P_ID;
  121.     uint16_t P_ADR;
  122.     uint16_t A_ID;
  123.     uint16_t A_ADR;
  124.     uint8_t  VccMin;
  125.     uint8_t  VccMax;
  126.     uint8_t  VppMin;
  127.     uint8_t  VppMax;
  128.     uint8_t  WordWriteTimeoutTyp;
  129.     uint8_t  BufWriteTimeoutTyp;
  130.     uint8_t  BlockEraseTimeoutTyp;
  131.     uint8_t  ChipEraseTimeoutTyp;
  132.     uint8_t  WordWriteTimeoutMax;
  133.     uint8_t  BufWriteTimeoutMax;
  134.     uint8_t  BlockEraseTimeoutMax;
  135.     uint8_t  ChipEraseTimeoutMax;
  136.     uint8_t  DevSize;
  137.     uint16_t InterfaceDesc;
  138.     uint16_t MaxBufWriteSize;
  139.     uint8_t  NumEraseRegions;
  140.     uint32_t EraseRegionInfo[0]; /* Not host ordered */
  141. } __attribute__((packed));
  142.  
  143. /* Extended Query Structure for both PRI and ALT */
  144.  
  145. struct cfi_extquery {
  146.     uint8_t  pri[3];
  147.     uint8_t  MajorVersion;
  148.     uint8_t  MinorVersion;
  149. } __attribute__((packed));
  150.  
  151. /* Vendor-Specific PRI for Intel/Sharp Extended Command Set (0x0001) */
  152.  
  153. struct cfi_pri_intelext {
  154.     uint8_t  pri[3];
  155.     uint8_t  MajorVersion;
  156.     uint8_t  MinorVersion;
  157.     uint32_t FeatureSupport; /* if bit 31 is set then an additional uint32_t feature
  158.                     block follows - FIXME - not currently supported */
  159.     uint8_t  SuspendCmdSupport;
  160.     uint16_t BlkStatusRegMask;
  161.     uint8_t  VccOptimal;
  162.     uint8_t  VppOptimal;
  163.     uint8_t  NumProtectionFields;
  164.     uint16_t ProtRegAddr;
  165.     uint8_t  FactProtRegSize;
  166.     uint8_t  UserProtRegSize;
  167.     uint8_t  extra[0];
  168. } __attribute__((packed));
  169.  
  170. struct cfi_intelext_otpinfo {
  171.     uint32_t ProtRegAddr;
  172.     uint16_t FactGroups;
  173.     uint8_t  FactProtRegSize;
  174.     uint16_t UserGroups;
  175.     uint8_t  UserProtRegSize;
  176. } __attribute__((packed));
  177.  
  178. struct cfi_intelext_blockinfo {
  179.     uint16_t NumIdentBlocks;
  180.     uint16_t BlockSize;
  181.     uint16_t MinBlockEraseCycles;
  182.     uint8_t  BitsPerCell;
  183.     uint8_t  BlockCap;
  184. } __attribute__((packed));
  185.  
  186. struct cfi_intelext_regioninfo {
  187.     uint16_t NumIdentPartitions;
  188.     uint8_t  NumOpAllowed;
  189.     uint8_t  NumOpAllowedSimProgMode;
  190.     uint8_t  NumOpAllowedSimEraMode;
  191.     uint8_t  NumBlockTypes;
  192.     struct cfi_intelext_blockinfo BlockTypes[1];
  193. } __attribute__((packed));
  194.  
  195. struct cfi_intelext_programming_regioninfo {
  196.     uint8_t  ProgRegShift;
  197.     uint8_t  Reserved1;
  198.     uint8_t  ControlValid;
  199.     uint8_t  Reserved2;
  200.     uint8_t  ControlInvalid;
  201.     uint8_t  Reserved3;
  202. } __attribute__((packed));
  203.  
  204. /* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */
  205.  
  206. struct cfi_pri_amdstd {
  207.     uint8_t  pri[3];
  208.     uint8_t  MajorVersion;
  209.     uint8_t  MinorVersion;
  210.     uint8_t  SiliconRevision; /* bits 1-0: Address Sensitive Unlock */
  211.     uint8_t  EraseSuspend;
  212.     uint8_t  BlkProt;
  213.     uint8_t  TmpBlkUnprotect;
  214.     uint8_t  BlkProtUnprot;
  215.     uint8_t  SimultaneousOps;
  216.     uint8_t  BurstMode;
  217.     uint8_t  PageMode;
  218.     uint8_t  VppMin;
  219.     uint8_t  VppMax;
  220.     uint8_t  TopBottom;
  221. } __attribute__((packed));
  222.  
  223. /* Vendor-Specific PRI for Atmel chips (command set 0x0002) */
  224.  
  225. struct cfi_pri_atmel {
  226.     uint8_t pri[3];
  227.     uint8_t MajorVersion;
  228.     uint8_t MinorVersion;
  229.     uint8_t Features;
  230.     uint8_t BottomBoot;
  231.     uint8_t BurstMode;
  232.     uint8_t PageMode;
  233. } __attribute__((packed));
  234.  
  235. struct cfi_pri_query {
  236.     uint8_t  NumFields;
  237.     uint32_t ProtField[1]; /* Not host ordered */
  238. } __attribute__((packed));
  239.  
  240. struct cfi_bri_query {
  241.     uint8_t  PageModeReadCap;
  242.     uint8_t  NumFields;
  243.     uint32_t ConfField[1]; /* Not host ordered */
  244. } __attribute__((packed));
  245.  
  246. #define P_ID_NONE               0x0000
  247. #define P_ID_INTEL_EXT          0x0001
  248. #define P_ID_AMD_STD            0x0002
  249. #define P_ID_INTEL_STD          0x0003
  250. #define P_ID_AMD_EXT            0x0004
  251. #define P_ID_WINBOND            0x0006
  252. #define P_ID_ST_ADV             0x0020
  253. #define P_ID_MITSUBISHI_STD     0x0100
  254. #define P_ID_MITSUBISHI_EXT     0x0101
  255. #define P_ID_SST_PAGE           0x0102
  256. #define P_ID_INTEL_PERFORMANCE  0x0200
  257. #define P_ID_INTEL_DATA         0x0210
  258. #define P_ID_RESERVED           0xffff
  259.  
  260.  
  261. #define CFI_MODE_CFI    1
  262. #define CFI_MODE_JEDEC    0
  263.  
  264. struct cfi_private {
  265.     uint16_t cmdset;
  266.     void *cmdset_priv;
  267.     int interleave;
  268.     int device_type;
  269.     int cfi_mode;        /* Are we a JEDEC device pretending to be CFI? */
  270.     int addr_unlock1;
  271.     int addr_unlock2;
  272.     struct mtd_info *(*cmdset_setup)(struct map_info *);
  273.     struct cfi_ident *cfiq; /* For now only one. We insist that all devs
  274.                   must be of the same type. */
  275.     int mfr, id;
  276.     int numchips;
  277.     unsigned long chipshift; /* Because they're of the same type */
  278.     const char *im_name;     /* inter_module name for cmdset_setup */
  279.     struct flchip chips[0];  /* per-chip data structure for each chip */
  280. };
  281.  
  282. /*
  283.  * Returns the command address according to the given geometry.
  284.  */
  285. static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs,
  286.                 struct map_info *map, struct cfi_private *cfi)
  287. {
  288.     unsigned bankwidth = map_bankwidth(map);
  289.     unsigned interleave = cfi_interleave(cfi);
  290.     unsigned type = cfi->device_type;
  291.     uint32_t addr;
  292.     
  293.     addr = (cmd_ofs * type) * interleave;
  294.  
  295.     /* Modify the unlock address if we are in compatiblity mode.
  296.      * For 16bit devices on 8 bit busses
  297.      * and 32bit devices on 16 bit busses
  298.      * set the low bit of the alternating bit sequence of the address.
  299.      */
  300.     if (((type * interleave) > bankwidth) && ((uint8_t)cmd_ofs == 0xaa))
  301.         addr |= (type >> 1)*interleave;
  302.  
  303.     return  addr;
  304. }
  305.  
  306. /*
  307.  * Transforms the CFI command for the given geometry (bus width & interleave).
  308.  * It looks too long to be inline, but in the common case it should almost all
  309.  * get optimised away.
  310.  */
  311. static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi)
  312. {
  313.     map_word val = { {0} };
  314.     int wordwidth, words_per_bus, chip_mode, chips_per_word;
  315.     unsigned long onecmd;
  316.     int i;
  317.  
  318.     /* We do it this way to give the compiler a fighting chance
  319.        of optimising away all the crap for 'bankwidth' larger than
  320.        an unsigned long, in the common case where that support is
  321.        disabled */
  322.     if (map_bankwidth_is_large(map)) {
  323.         wordwidth = sizeof(unsigned long);
  324.         words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1
  325.     } else {
  326.         wordwidth = map_bankwidth(map);
  327.         words_per_bus = 1;
  328.     }
  329.  
  330.     chip_mode = map_bankwidth(map) / cfi_interleave(cfi);
  331.     chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map);
  332.  
  333.     /* First, determine what the bit-pattern should be for a single
  334.        device, according to chip mode and endianness... */
  335.     switch (chip_mode) {
  336.     default: BUG();
  337.     case 1:
  338.         onecmd = cmd;
  339.         break;
  340.     case 2:
  341.         onecmd = cpu_to_cfi16(cmd);
  342.         break;
  343.     case 4:
  344.         onecmd = cpu_to_cfi32(cmd);
  345.         break;
  346.     }
  347.  
  348.     /* Now replicate it across the size of an unsigned long, or
  349.        just to the bus width as appropriate */
  350.     switch (chips_per_word) {
  351.     default: BUG();
  352. #if BITS_PER_LONG >= 64
  353.     case 8:
  354.         onecmd |= (onecmd << (chip_mode * 32));
  355. #endif
  356.     case 4:
  357.         onecmd |= (onecmd << (chip_mode * 16));
  358.     case 2:
  359.         onecmd |= (onecmd << (chip_mode * 8));
  360.     case 1:
  361.         ;
  362.     }
  363.  
  364.     /* And finally, for the multi-word case, replicate it
  365.        in all words in the structure */
  366.     for (i=0; i < words_per_bus; i++) {
  367.         val.x[i] = onecmd;
  368.     }
  369.  
  370.     return val;
  371. }
  372. #define CMD(x)  cfi_build_cmd((x), map, cfi)
  373.  
  374.  
  375. static inline unsigned long cfi_merge_status(map_word val, struct map_info *map,
  376.                        struct cfi_private *cfi)
  377. {
  378.     int wordwidth, words_per_bus, chip_mode, chips_per_word;
  379.     unsigned long onestat, res = 0;
  380.     int i;
  381.  
  382.     /* We do it this way to give the compiler a fighting chance
  383.        of optimising away all the crap for 'bankwidth' larger than
  384.        an unsigned long, in the common case where that support is
  385.        disabled */
  386.     if (map_bankwidth_is_large(map)) {
  387.         wordwidth = sizeof(unsigned long);
  388.         words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1
  389.     } else {
  390.         wordwidth = map_bankwidth(map);
  391.         words_per_bus = 1;
  392.     }
  393.  
  394.     chip_mode = map_bankwidth(map) / cfi_interleave(cfi);
  395.     chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map);
  396.  
  397.     onestat = val.x[0];
  398.     /* Or all status words together */
  399.     for (i=1; i < words_per_bus; i++) {
  400.         onestat |= val.x[i];
  401.     }
  402.  
  403.     res = onestat;
  404.     switch(chips_per_word) {
  405.     default: BUG();
  406. #if BITS_PER_LONG >= 64
  407.     case 8:
  408.         res |= (onestat >> (chip_mode * 32));
  409. #endif
  410.     case 4:
  411.         res |= (onestat >> (chip_mode * 16));
  412.     case 2:
  413.         res |= (onestat >> (chip_mode * 8));
  414.     case 1:
  415.         ;
  416.     }
  417.  
  418.     /* Last, determine what the bit-pattern should be for a single
  419.        device, according to chip mode and endianness... */
  420.     switch (chip_mode) {
  421.     case 1:
  422.         break;
  423.     case 2:
  424.         res = cfi16_to_cpu(res);
  425.         break;
  426.     case 4:
  427.         res = cfi32_to_cpu(res);
  428.         break;
  429.     default: BUG();
  430.     }
  431.     return res;
  432. }
  433.  
  434. #define MERGESTATUS(x) cfi_merge_status((x), map, cfi)
  435.  
  436.  
  437. /*
  438.  * Sends a CFI command to a bank of flash for the given geometry.
  439.  *
  440.  * Returns the offset in flash where the command was written.
  441.  * If prev_val is non-null, it will be set to the value at the command address,
  442.  * before the command was written.
  443.  */
  444. static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t base,
  445.                 struct map_info *map, struct cfi_private *cfi,
  446.                 int type, map_word *prev_val)
  447. {
  448.     map_word val;
  449.     uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, map, cfi);
  450.     val = cfi_build_cmd(cmd, map, cfi);
  451.  
  452.     if (prev_val)
  453.         *prev_val = map_read(map, addr);
  454.  
  455.     map_write(map, val, addr);
  456.  
  457.     return addr - base;
  458. }
  459.  
  460. static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr)
  461. {
  462.     map_word val = map_read(map, addr);
  463.  
  464.     if (map_bankwidth_is_1(map)) {
  465.         return val.x[0];
  466.     } else if (map_bankwidth_is_2(map)) {
  467.         return cfi16_to_cpu(val.x[0]);
  468.     } else {
  469.         /* No point in a 64-bit byteswap since that would just be
  470.            swapping the responses from different chips, and we are
  471.            only interested in one chip (a representative sample) */
  472.         return cfi32_to_cpu(val.x[0]);
  473.     }
  474. }
  475.  
  476. static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr)
  477. {
  478.     map_word val = map_read(map, addr);
  479.  
  480.     if (map_bankwidth_is_1(map)) {
  481.         return val.x[0] & 0xff;
  482.     } else if (map_bankwidth_is_2(map)) {
  483.         return cfi16_to_cpu(val.x[0]);
  484.     } else {
  485.         /* No point in a 64-bit byteswap since that would just be
  486.            swapping the responses from different chips, and we are
  487.            only interested in one chip (a representative sample) */
  488.         return cfi32_to_cpu(val.x[0]);
  489.     }
  490. }
  491.  
  492. static inline void cfi_udelay(int us)
  493. {
  494.     if (us >= 1000) {
  495.         msleep((us+999)/1000);
  496.     } else {
  497.         udelay(us);
  498.         cond_resched();
  499.     }
  500. }
  501.  
  502. int __xipram cfi_qry_present(struct map_info *map, __u32 base,
  503.                  struct cfi_private *cfi);
  504. int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map,
  505.                  struct cfi_private *cfi);
  506. void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map,
  507.                    struct cfi_private *cfi);
  508.  
  509. struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size,
  510.                  const char* name);
  511. struct cfi_fixup {
  512.     uint16_t mfr;
  513.     uint16_t id;
  514.     void (*fixup)(struct mtd_info *mtd, void* param);
  515.     void* param;
  516. };
  517.  
  518. #define CFI_MFR_ANY 0xffff
  519. #define CFI_ID_ANY  0xffff
  520.  
  521. #define CFI_MFR_AMD 0x0001
  522. #define CFI_MFR_ATMEL 0x001F
  523. #define CFI_MFR_ST  0x0020     /* STMicroelectronics */
  524.  
  525. void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups);
  526.  
  527. typedef int (*varsize_frob_t)(struct map_info *map, struct flchip *chip,
  528.                   unsigned long adr, int len, void *thunk);
  529.  
  530. int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
  531.     loff_t ofs, size_t len, void *thunk);
  532.  
  533.  
  534. #endif /* __MTD_CFI_H__ */
  535.